package com.cn.jwt.zy.jwt.config;

import io.jsonwebtoken.*;
import org.springframework.boot.context.properties.ConfigurationProperties;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Date;

/**
 * 解析jwt类
 *
 * @author zhangyi
 * @date 2018/12/14 14:05
 */
@ConfigurationProperties(prefix = "zy.jwt")
public class JwtHelpr {


    private Long expire;
    private String secret;


    /**
     * 解析token数据
     *
     * @param jsonwebToken
     * @param base64Security
     * @return
     */
    public static Claims parseJwt(String jsonwebToken,String base64Security){
        try{
            Claims body = Jwts.parser()
                    .setSigningKey(DatatypeConverter.parseBase64Binary(base64Security))
                    .parseClaimsJws(jsonwebToken).getBody();
            return body;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 生成token
     *
     * @param name
     * @param userId
     * @param role
     * @param TTLMillis
     * @param base64Security
     * @return
     */
    public static String createJwt(String name, String userId, String role,
                                   long TTLMillis,
                                   String base64Security){
        //使用指定的签名算法
        SignatureAlgorithm signatureAlgorithm  = SignatureAlgorithm.HS256;

        //获取当前时间
        long nowMillis = System.currentTimeMillis();

        Date now = new Date(nowMillis);

        //生成签名密钥
    /*    byte[] apiKeySecretBytes  = DatatypeConverter.parseBase64Binary(base64Security);

        SecretKeySpec signingKey  = new SecretKeySpec(apiKeySecretBytes,signatureAlgorithm.getJcaName());
    */
        //密钥生成器
        KeyGenerator keyGen = null;
        try {
            keyGen = KeyGenerator.getInstance(signatureAlgorithm.getJcaName());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        //生成密钥
        SecretKey secretKey = keyGen.generateKey();

    JwtBuilder jwtBuilder = Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .claim("role", role)
                .claim("userName", name)
                .claim("userId", userId)
                .signWith(signatureAlgorithm, secretKey);

        //添加token过期时间
        if(TTLMillis >= 0){
            long expMillis = nowMillis + TTLMillis;
            Date exp = new Date(expMillis);
            jwtBuilder.setExpiration(exp).setNotBefore(now);
        }

        return jwtBuilder.compact();
    }

//    ----------------------------------------------

    /**
     * 生成jwt token
     */
    public String generateToken(long userId) {
        long expire = 680090;
        String secret = "123";
        Date nowDate = new Date();
        //过期时间
        Date expireDate = new Date(nowDate.getTime() + expire * 1000);

        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS512;
        //生成加密密钥
        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(userId+"")
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(signatureAlgorithm, "123")
                .compact();
    }

    /**
     * 解析token
     *
     * @param token
     * @return
     */
    public  Claims getClaimByToken(String token) {
        String secret = "123";
        try {
            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS512;
            return Jwts.parser()
                    .setSigningKey("123")
                    .parseClaimsJws(token)
                    .getBody();
        }catch (Exception e){
            System.out.println("jwt 揭秘失败");
            return null;
        }
    }

    public Long getExpire() {
        return expire;
    }

    public void setExpire(Long expire) {
        this.expire = expire;
    }

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }
}
